﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Microsoft.VisualBasic;


namespace FIS.iDET
{
    public partial class InputToolForm : Form
    {
        // the autosaved excel file
        private ExcelService autosaveExcelFile = null;

        // search direction
        private bool findDown = true;

        // current image
        private ImageService tifImage;

        // the user's working excel file
        private ExcelService userExcelFile = null;

        public InputToolForm()
        {
            InitializeComponent();

            gTooltip = Graphics.FromHwnd(label1.Handle);
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormAbout aboutForm = new FormAbout();
            aboutForm.ShowDialog();
        }

        private void comboBoxDateFormat_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tifImage != null)
            {
                /*
                for (int i = 0; i < tifImage.TotalFrames; i++)
                    if (dataGridViewInput[0, i].Value != null)
                        ConvertCellValueToDateTime(dataGridViewInput[0, i]);
                 */

                // TOCHECK programatically apply to all columns having type date
                for (int i = 0; i < GlobalConstants.Columns.Count; i++)
                {
                    if (GlobalConstants.Columns[i].Type == DataTypeEnum.COLUMN_TYPE_DATE)
                        dataGridViewInput.Columns[i].DefaultCellStyle.Format = comboBoxDateFormat.Text;
                }
            }
        }

        private void ConvertCellValueToDateTime(DataGridViewCell cell)
        {
            DateTime dateTime;
            if (DateTime.TryParse(cell.Value.ToString(), out dateTime))

                //cell.Value = dateTime.ToString(comboBoxDateFormat.Text);
                cell.Value = dateTime;
        }

        private void CreateNewExcelFile()
        {
            // reset data grid view
            ResetDataGridView();

            // define new empty excel file
            userExcelFile.FileName = null;
            userExcelFile.Saved = true;

            // save to registry
            RegistryService.SetValue(GlobalConstants.REGISTRY_LAST_EXCEL_KEY, GlobalConstants.REGISTRY_LAST_EXCEL_NULL_VALUE);
            this.Text = "FIS.iDET: Unsaved";
        }

        private void dataGridViewInput_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            // hide tooltip
            if (navigationToolStripMenuItem.Checked)
                toolTipPictBox.Hide(PictBox);

            // when user makes change to data
            if (userExcelFile.Saved)
            {
                // set excel file status to unsaved
                userExcelFile.Saved = false;

                // add * in app caption
                if (Text.IndexOf('*') == -1)
                {
                    Text = Text.Trim() + '*';
                }

                // enable save buttons
                EnableSaveButton(true);

                // start autosave
                timerAutosave.Start();
            }

            // format date
            // TODO get column index to parse as datetime from GlobalConstants.ColumnTypes[]
            if (GlobalConstants.IsDateColumn(e.ColumnIndex) &&
                e.RowIndex > -1 && dataGridViewInput.CurrentCell != null &&
                dataGridViewInput.CurrentCell.Value != null)
            {
                // try to parse cell value to date
                ConvertCellValueToDateTime(dataGridViewInput.CurrentCell);
            }
        }

        private void dataGridViewInput_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.ColumnIndex == -1 && e.RowIndex > -1)
            {
                e.PaintBackground(e.CellBounds, true);
                using (SolidBrush br = new SolidBrush(Color.Black))
                {
                    StringFormat sf = new StringFormat();
                    sf.Alignment = StringAlignment.Center;
                    sf.LineAlignment = StringAlignment.Center;
                    e.Graphics.DrawString((e.RowIndex + 1).ToString(), e.CellStyle.Font, br, e.CellBounds, sf);
                }
                e.Handled = true;
            }
        }

        private void dataGridViewInput_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
        {
            // make all columns unsortable
            e.Column.SortMode = DataGridViewColumnSortMode.NotSortable;
        }

        private void dataGridViewInput_KeyUp(object sender, KeyEventArgs e)
        {
            ClipboardUtils.OnDataGridPaste(sender, e);
        }

        private void DeleteDataGridView()
        {
            // clear data grid
            if (dataGridViewInput.DataSource == null)
                dataGridViewInput.Columns.Clear();
            else
                dataGridViewInput.DataSource = null;
        }

        private void EnableMenuIcons(Boolean enabled)
        {
            saveDataAsToolStripMenuItem.Enabled = enabled;
            if (GlobalConstants.TemplatePageCol == 0) // H.NH added
                newExcelFileToolStripMenuItem.Enabled = enabled;
            loadExcelFileToolStripMenuItem.Enabled = enabled;
            if (GlobalConstants.TemplatePageCol == 0)
                toolStripButtonNewData.Enabled = enabled; // H.NH added
            toolStripButtonNextPage.Enabled = enabled;
            toolStripButtonPreviousPage.Enabled = enabled;
            toolStripButtonFind.Enabled = enabled;
            toolStripTextBoxFind.Enabled = enabled;
            toolStripButtonFindDirection.Enabled = enabled;
            comboBoxDateFormat.Enabled = enabled;
            toolStripTextBoxPageNumber.Enabled = enabled;
            goToPageToolStripMenuItem.Enabled = enabled;
            findToolStripMenuItem.Enabled = enabled;
            toolStripComboBoxZoomRatio.Enabled = enabled;
            toolStripButtonZoomOut.Enabled = enabled;
            toolStripButtonZoomIn.Enabled = enabled;
            navigationToolStripMenuItem.Enabled = enabled;
            toolStripButtonNavigationGuide.Enabled = enabled;
            toolStripButtonZoomFit.Enabled = enabled;
            PictBox.Enabled = enabled;
            toolStripOpenExcelFileButton.Enabled = enabled;
            /* moveTooltipDownToolStripMenuItem.Enabled = moveTooltipLeftToolStripMenuItem.Enabled =
                moveTooltipUpToolStripMenuItem.Enabled = moveTooltipRightToolStripMenuItem.Enabled =
                increaseTooltipHeightToolStripMenuItem.Enabled = increaseTooltipWidthToolStripMenuItem.Enabled =
                decreaseTooltipHeightToolStripMenuItem.Enabled = decreaseTooltipWidthToolStripMenuItem.Enabled = enabled; */
            navigationToolStripMenuItem.Enabled = toolStripButtonNavigationGuide.Enabled = enabled;
            //H.NH add
            toolStripComboBoxPosSpin.SelectedIndex = 0;
            toolStripComboBoxPosSpin.Enabled = enabled;
        }

        private void EnableSaveButton(Boolean enable)
        {
            saveDataToolStripMenuItem.Enabled = enable;
            toolStripButtonSaveData.Enabled = enable;
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // this makes sure form closing event is called
            // so that user is asked to save data before closing app
            this.Close();
        }

        private void findToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripTextBoxFind.Focus();
            toolStripTextBoxFind.SelectAll();
        }

        private void goToPageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripTextBoxPageNumber.Focus();
            toolStripTextBoxPageNumber.SelectAll();
        }

        private void helpsubToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string appPath = Application.ExecutablePath;
            try
            {
                appPath = appPath.Remove(appPath.LastIndexOf('\\'));
                Process.Start(appPath + "\\Help.htm");
            }
            catch
            {
                MessageBox.Show("Sorry, can not find Help files.Please try again!", "No help files", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }

        private void InputToolForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            SaveApplicationOption();
        }

        private void InputToolForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // asks user to save data file, if it is not saved
            // if user clicks cancel, stop
            if (!PromptIfDataNotSaved())
            {
                e.Cancel = true;
                return;
            }

            // exit excel app
            if (autosaveExcelFile != null)
                autosaveExcelFile.QuitExcelApp();
            if (userExcelFile != null)
                userExcelFile.QuitExcelApp();

            // delete autosave file
            if (autosaveExcelFile != null && autosaveExcelFile.FileExists)
                File.Delete(autosaveExcelFile.FileName);
        }

        private void InputToolForm_Load(object sender, EventArgs e)
        {
            // init registry service

            RegistryService.Init();

            // if app is not activated
            if (!LicenseService.AppIsActivated())
            {
                // show license windows
                LicenseKeyForm licenseKeyForm = new LicenseKeyForm();
                licenseKeyForm.ShowDialog();
            }

            // otherwise
            // run the app
            else
            {
                // init app options
                GlobalConstants.OptionInit();

                // init user excel file
                userExcelFile = new ExcelService();

                // init autosave excel file
                // the temporary directory to store autosave file
                string autosaveDirectory = Path.GetTempPath() + GlobalConstants.COMPANY_NAME;

                // create temp folder, if needed
                if (!Directory.Exists(autosaveDirectory))
                    Directory.CreateDirectory(autosaveDirectory);

                // assign full filename to autosave excel file
                autosaveExcelFile = new ExcelService(autosaveDirectory + "\\" + GlobalConstants.AUTOSAVE_FILENAME);

                // if recovery file exists
                // show recovery dialog box
                if (autosaveExcelFile.FileExists)
                    ShowRecoveryDialog();

                // set last working files to nothing
                RegistryService.SetValue(GlobalConstants.REGISTRY_LAST_IMAGE_KEY, GlobalConstants.REGISTRY_LAST_IMAGE_NULL_VALUE);
                RegistryService.SetValue(GlobalConstants.REGISTRY_LAST_EXCEL_KEY, GlobalConstants.REGISTRY_LAST_EXCEL_NULL_VALUE);
                this.Text = "FIS.iDET: Unsaved";

                // load application last options
                LoadApplicationOption();
            }
        }

        /// <summary>
        /// check if a string is found in data grid view's cell [i, j]
        /// </summary>
        /// <param name="whatToFind">string to find</param>
        /// <param name="i">row index of data grid view cell to check</param>
        /// <param name="j">comun index of data grid view cell to check</param>
        /// <returns></returns>
        private bool IsFound(string whatToFind, int i, int j)
        {
            if (dataGridViewInput.Rows[i].Cells[j].Value == null)
                return false;
            string parentString = dataGridViewInput.Rows[i].Cells[j].Value.ToString();

            // TODO programmatically loop thru every column with type date
            // to convert that date to string with user's date format setting before checking
            if (GlobalConstants.IsDateColumn(j)) // date column
            {
                DateTime validDate;
                if (DateTime.TryParse(parentString, out validDate))
                    return validDate.ToString(comboBoxDateFormat.Text).ToLowerInvariant().Contains(whatToFind);
                else
                    return parentString.ToLowerInvariant().Contains(whatToFind);
            }
            else
                return parentString.ToLowerInvariant().Contains(whatToFind);
        }

        private void LoadApplicationOption()
        {
            // comboBox Date Format index
            comboBoxDateFormat.SelectedIndex = GlobalConstants.ComboBoxDateFormatIndex;
        }

        private void loadExcelFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenExcelFile();
        }

        private void LoadImage()
        {
            // check if image template is loaded
            // if not, ask user to
            if (GlobalConstants.Columns == null)
            {
                MessageBox.Show("Please load an image template first! A windows will now appear for you to load such template.");
                if (!LoadTemplate())
                    return;
            }

            // ask if user wants to save data file
            // stop if user clicks cancel
            if (!PromptIfDataNotSaved()) return;

            // show open image file dialog
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Tif Images|*.tif|Tiff Images|*.tiff|All files|*.*";
            openFileDialog.Title = "Open Tiff Image";
            DialogResult result = openFileDialog.ShowDialog();

            if (result == DialogResult.OK && !String.IsNullOrEmpty(openFileDialog.FileName))
            {
                // load tif file
                tifImage = new ImageService(openFileDialog.FileName);

                if (tifImage.FileLoadedOK)
                {
                    // if template is in multipage mode, asks user to load excel file for this mode to work
                    if (GlobalConstants.TemplatePageCol != 0)
                    {
                        if (MessageBox.Show("You are working in multipage mode, do you want to load an Excel data file for this mode to work?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                        {
                            if (!OpenExcelFile())
                            {
                                ResetImageBox();
                                return;
                            }
                            else
                            {
                                // toolStripTextBoxPageNumber.ReadOnly = true; rem by H.NH
                            }
                        }
                        else
                        {
                            string rowsPerPage = "";
                            rowsPerPage = Interaction.InputBox("Please input the number of rows per page:", "Create new Excel File", "10");
                            int rowspp = 10;
                            int.TryParse(rowsPerPage, out rowspp);
                            if (rowspp > 0)
                            {
                                ResetDataGridView();
                                dataGridViewInput.Rows.Add(rowspp * tifImage.TotalFrames);
                                for (int page = 1; page <= tifImage.TotalFrames; page++)
                                {
                                    for (int row = 1; row <= rowspp; row++)
                                    {                                        
                                        dataGridViewInput.Rows[(page-1)*rowspp+row-1].Cells[GlobalConstants.TemplatePageCol - 1].Value = page.ToString();
                                    }
                                }                                
                            }
                            else
                            {
                                MessageBox.Show("Wrong number!");
                                ResetImageBox();
                                return;
                            }
                        }
                    }
                    else
                    {
                        // toolStripTextBoxPageNumber.ReadOnly = false;

                        // create new excel file
                        CreateNewExcelFile();
                    }

                    // set max page to toolStripLabelPage
                    toolStripLabelPage.Text = " / " + tifImage.TotalFrames.ToString();

                    // enable menu items
                    EnableMenuIcons(true);

                    // disable previous page button
                    toolStripButtonPreviousPage.Enabled = false;

                    // disable next page button if there is just one page
                    if (tifImage.TotalFrames == 1)
                        toolStripButtonNextPage.Enabled = false;

                    // disable save buttons as there is no data to save yet
                    EnableSaveButton(false);

                    // set image file name to registry
                    RegistryService.SetValue(GlobalConstants.REGISTRY_LAST_IMAGE_KEY, openFileDialog.FileName);
                    // set combobox zoom index
                    toolStripComboBoxZoomRatio.SelectedIndex = GlobalConstants.ComboBoxZoomIndex;

                    // set default zoom factor
                    zoomFactor = GlobalConstants.TemplateZoom;
                    toolStripComboBoxZoomRatio.Text = ((int)(zoomFactor*100)).ToString() + "%";
                    KeyPressEventArgs key = new KeyPressEventArgs((char) Keys.Enter);
                    toolStripComboBoxZoomRatio_KeyPress(null, key);
                }
                else
                {
                    ResetImageBox();
                }
            }
        }

        private void ResetImageBox()
        {
            // delete data grid view since no image is loaded
            DeleteDataGridView();

            // delete image
            PictBox.Image = null;

            // disable menu items
            EnableMenuIcons(false);
            EnableSaveButton(false);

            // set no image to registry
            RegistryService.SetValue(GlobalConstants.REGISTRY_LAST_IMAGE_KEY, GlobalConstants.REGISTRY_LAST_IMAGE_NULL_VALUE);
        }

        private void loadImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadImage();
        }

        private void newExcelFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // inform user that working data are not saved
            // stop if user clicks cancel
            if (!PromptIfDataNotSaved()) return;

            CreateNewExcelFile();
        }

        private bool OpenExcelFile()
        {
            // ask if user wants to save data file
            // stop if user clicks cancel
            if (!PromptIfDataNotSaved()) return false;

            // show open excel file dialog
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Excel files|*.xls|New Excel files|*.xlsx|All files|*.*";
            openFileDialog.Title = "Open Excel File";
            DialogResult result = openFileDialog.ShowDialog();

            if (result == DialogResult.OK && !String.IsNullOrEmpty(openFileDialog.FileName))
            {
                try
                {
                    // clear datagrid
                    ResetDataGridView();

                    // move focus out of datagridview, what this really does?
                    // toolStripTextBoxPageNumber.Focus();

                    // import data from excel to data grid view
                    userExcelFile.ImportDataFromExcelFile(openFileDialog.FileName, ref dataGridViewInput);

                    // set current excel file to the file 've just open.
                    userExcelFile.FileName = openFileDialog.FileName;

                    // push excel file name to Autosave Registry
                    RegistryService.SetValue(GlobalConstants.REGISTRY_LAST_EXCEL_KEY, openFileDialog.FileName);
                    this.Text = "FIS.iDET: " + openFileDialog.FileName;

                    // move focus in to datagridview
                    //dataGridViewInput.Focus();
                }
                catch (Exception e)
                {
                    MessageBox.Show("Error: " + e.Message);
                    return false;
                }
            }
            else
                return false;

            return true;
        }

        /// <summary>
        /// shows a message box asking user to save data before continuing next action
        /// </summary>
        /// <returns>true if user has decided to go on (ie user clicks on button YES or NO), false if user clicks on CANCEL</returns>
        private Boolean PromptIfDataNotSaved()
        {
            if (dataGridViewInput != null && userExcelFile != null)
            {
                // if working data are not saved
                if (!userExcelFile.Saved && dataGridViewInput.ColumnCount > 0)
                {
                    // asks if user want to save it
                    DialogResult result = MessageBox.Show("Do you want to save your current data?", "Unsaved data", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button3);

                    if (result == DialogResult.Cancel)

                        // not continue
                        return false;
                    else if (result == DialogResult.Yes)
                    {
                        // if an working excel file exists
                        // save it
                        if (userExcelFile.FileName != null)
                        {
                            userExcelFile.SaveAs(dataGridViewInput);
                            return true;
                        }
                        else

                            // if no working excel file
                            // prompts user to choose one
                            return ShowSaveAsDialog();
                    }
                }
            }
            return true;// continue
        }

        private void ResetDataGridView()
        {
            // delete old data
            DeleteDataGridView();

            int allColumnWidth = 0;

            // set default column headers to data grid
            for (int i = 0; i < GlobalConstants.Columns.Count; i++)
            {
                dataGridViewInput.Columns.Add(GlobalConstants.Columns[i].Header, GlobalConstants.Columns[i].Header);
                dataGridViewInput.Columns[i].Width = GlobalConstants.Columns[i].Width;
                allColumnWidth += GlobalConstants.Columns[i].Width;
            }

            // set the page column read-only
            if (GlobalConstants.TemplatePageCol > 0 &&
                GlobalConstants.TemplatePageCol <= GlobalConstants.Columns.Count)
            {
                dataGridViewInput.Columns[GlobalConstants.TemplatePageCol - 1].ReadOnly = false; //H.NH change this to allow edit mode !
            }

            // add rows to data grid (in case of single line mode)
            if (tifImage != null && tifImage.TotalFrames != 0 && GlobalConstants.TemplatePageCol == 0)
                dataGridViewInput.Rows.Add(tifImage.TotalFrames);

            // in case of multi line mode, rows will be added on excel import

            // set date format style to date typed columns
            foreach (int i in GlobalConstants.DateColumnIndices)
                dataGridViewInput.Columns[i].DefaultCellStyle.Format = comboBoxDateFormat.Text;

            // resize container panel to fit datagridview's new width
            splitContainerApp.SplitterDistance = splitContainerApp.Width - allColumnWidth - 55;

            // dataGridViewInput.Refresh();
            // resize data grid view
            // dataGridViewInput.Width = allColumnWidth;
        }

        /// <summary>
        /// save application options to registry
        /// </summary>
        private void SaveApplicationOption()
        {
            RegistryService.SetValue(GlobalConstants.REGISTRY_DATE_FORMAT_INDEX, comboBoxDateFormat.SelectedIndex.ToString());
        }

        private void saveDataAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowSaveAsDialog();
        }

        private void saveDataToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveUserExcelFile();
        }

        private void SaveUserExcelFile()
        {
            // stop edit mode
            dataGridViewInput.EndEdit();

            // in case this is called for first time, prompts user to choose a file path
            if (userExcelFile.FileName == null)
                ShowSaveAsDialog();
            else
            {
                // save the file
                userExcelFile.SaveAs(dataGridViewInput);

                // stop autosave as file is updated
                timerAutosave.Stop();

                // diasable save buttons
                EnableSaveButton(false);

                // clear * in app name
                Text = Text.Replace('*', ' ');
            }
        }

        private void SelectDataGridViewCell(int i, int j)
        {
            dataGridViewInput.CurrentCell = dataGridViewInput.Rows[i].Cells[j];

            // dataGridViewInput.Focus();
            // dataGridViewInput.BeginEdit(true);
        }

        private void ShowRecoveryDialog()
        {
            // get last working image file path
            string lastWorkingImageFile = RegistryService.GetValue(GlobalConstants.REGISTRY_LAST_IMAGE_KEY);

            // get last working excel file path
            string lastWorkingExcelFile = RegistryService.GetValue(GlobalConstants.REGISTRY_LAST_EXCEL_KEY);

            // show recovery dialog box
            DialogResult result = MessageBox.Show(
                "It seems like Application crashed last time you were working onf" +
                "\nImage file: " + lastWorkingImageFile +
                "\nExcel file: " + lastWorkingExcelFile +
                "\n\nFortunately we found an auto-saved version your data, do you want to recover it?",
                "Data recovery",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question,
                MessageBoxDefaultButton.Button1
            );

            // copy autosave file to new location
            if (result == DialogResult.Yes)
                autosaveExcelFile.Recover();
        }

        private Boolean ShowSaveAsDialog()
        {
            // exit edit mode to update last working cell of data grid
            dataGridViewInput.EndEdit();

            // show save file dialog box
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Excel|*.xls";
            saveFileDialog.Title = "Save as Excel File";
            DialogResult result = saveFileDialog.ShowDialog();

            if (result == DialogResult.OK && !String.IsNullOrEmpty(saveFileDialog.FileName))
            {
                // set file name to user excel file
                userExcelFile.FileName = saveFileDialog.FileName;

                // save file
                userExcelFile.SaveAs(dataGridViewInput);

                // stop autosave
                timerAutosave.Stop();

                // disable save buttons
                EnableSaveButton(false);

                // update to registry
                RegistryService.SetValue(GlobalConstants.REGISTRY_LAST_EXCEL_KEY, saveFileDialog.FileName);
                this.Text = "FIS.iDET: " + saveFileDialog.FileName;

                // save succeeds
                return true;
            }

            // save fails
            return false;
        }

        /*** Menu Handlers ***/

        private void timerAutosave_Tick(object sender, EventArgs e)
        {
            if (!userExcelFile.Saved)
                    autosaveExcelFile.SaveAsAutoSave(dataGridViewInput);
        }

        private void toolStripButtonFind_Click(object sender, EventArgs e)
        {
            if (dataGridViewInput.RowCount == 0) return;

            if (dataGridViewInput.CurrentCell == null || dataGridViewInput.CurrentCell.RowIndex < 0 || dataGridViewInput.CurrentCell.ColumnIndex < 0)
                dataGridViewInput.CurrentCell = dataGridViewInput.Rows[0].Cells[0];

            if (toolStripTextBoxFind.Text.Length > 0)
            {
                // case-insensitive, with local language support
                string whatToFind = toolStripTextBoxFind.Text.ToLowerInvariant();

                // find down
                if (findDown)
                {
                    // first row
                    if (dataGridViewInput.CurrentCell.ColumnIndex != dataGridViewInput.ColumnCount)
                        for (int i = dataGridViewInput.CurrentCell.RowIndex, j = dataGridViewInput.CurrentCell.ColumnIndex + 1; j < dataGridViewInput.ColumnCount; j++)
                            if (IsFound(whatToFind, i, j))
                            {
                                SelectDataGridViewCell(i, j);
                                return;
                            }

                    // second to last row
                    if (dataGridViewInput.CurrentCell.RowIndex != dataGridViewInput.RowCount - 1)
                        for (int i = dataGridViewInput.CurrentCell.RowIndex + 1; i < dataGridViewInput.RowCount; i++)
                            for (int j = 0; j < dataGridViewInput.ColumnCount; j++)
                                if (IsFound(whatToFind, i, j))
                                {
                                    SelectDataGridViewCell(i, j);
                                    return;
                                }
                }

                // find up
                else
                {
                    // last row
                    if (dataGridViewInput.CurrentCell.ColumnIndex != 0)
                        for (int i = dataGridViewInput.CurrentCell.RowIndex, j = dataGridViewInput.CurrentCell.ColumnIndex - 1; j >= 0; j--)
                            if (IsFound(whatToFind, i, j))
                            {
                                SelectDataGridViewCell(i, j);
                                return;
                            }

                    // next to last row to first row
                    if (dataGridViewInput.CurrentCell.RowIndex != 0)
                        for (int i = dataGridViewInput.CurrentCell.RowIndex - 1; i >= 0; i--)
                            for (int j = dataGridViewInput.ColumnCount - 1; j >= 0; j--)
                                if (IsFound(whatToFind, i, j))
                                {
                                    SelectDataGridViewCell(i, j);
                                    return;
                                }
                }

                // nothing found
                MessageBox.Show("Cannot find \"" + toolStripTextBoxFind.Text + "\" " + (findDown ? "downward!" : "upward!"), "Search", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void toolStripButtonFindDirection_Click(object sender, EventArgs e)
        {
            // change button image
            toolStripButtonFindDirection.Image =
                findDown ?
                global::FIS.iDET.Properties.Resources.arrowUp :
                global::FIS.iDET.Properties.Resources.arrowDown;

            // change direction
            findDown = !findDown;
        }

        private void toolStripButtonNextPage_Click(object sender, EventArgs e)
        {
            if (GlobalConstants.TemplatePageCol == 0)
            {
                if (dataGridViewInput.CurrentCell.RowIndex < dataGridViewInput.RowCount)
                {
                    //DataGridViewCellEventArgs egv = new DataGridViewCellEventArgs(0, tifImage.CurrentFrame + 1);
                    //dataGridViewInput_RowEnter(sender, egv);
                    SelectDataGridViewCell(dataGridViewInput.CurrentCell.RowIndex + 1, dataGridViewInput.CurrentCell.ColumnIndex);
                }
            }
            else
            {
                int currentPageNumber = 0;
                int.TryParse(dataGridViewInput.Rows[dataGridViewInput.CurrentRow.Index].Cells[GlobalConstants.TemplatePageCol - 1].Value.ToString(), out currentPageNumber);                
                do
                {
                    currentPageNumber++;
                    if (FindPageInMultiMode(currentPageNumber) != -1) break;
                }
                while ( DialogResult.Yes == MessageBox.Show("Can't find page " + 
                    currentPageNumber.ToString()+". Do you want to go to page "+ (currentPageNumber+1).ToString() +" ?","Can not find required page",MessageBoxButtons.YesNo,MessageBoxIcon.Question));
                if (FindPageInMultiMode(currentPageNumber)>-1)
                    SelectDataGridViewCell(FindPageInMultiMode(currentPageNumber), dataGridViewInput.CurrentCell.ColumnIndex);
                // toolStripTextBoxPageNumber.Text = (++currentPageNumber).ToString();
                // KeyPressEventArgs key = new KeyPressEventArgs((char) Keys.Enter );               
                // toolStripTextBoxPageNumber_KeyPress(sender, key);

            }
        }

        private void toolStripButtonPreviousPage_Click(object sender, EventArgs e)
        {
            if (dataGridViewInput.CurrentCell.RowIndex > 0)
            {
                if (GlobalConstants.TemplatePageCol == 0)
                    //DataGridViewCellEventArgs egv = new DataGridViewCellEventArgs(0, tifImage.CurrentFrame - 1);
                    //dataGridViewInput_RowEnter(sender, egv);
                    SelectDataGridViewCell(dataGridViewInput.CurrentCell.RowIndex - 1, dataGridViewInput.CurrentCell.ColumnIndex);
                else
                {
                    int currentPageNumber = 0;
                    int.TryParse(dataGridViewInput.Rows[dataGridViewInput.CurrentRow.Index].Cells[GlobalConstants.TemplatePageCol - 1].Value.ToString(), out currentPageNumber);
                    do
                    {
                        currentPageNumber--;
                        if (FindPageInMultiMode(currentPageNumber) != -1) break;
                    }
                    while (currentPageNumber>0 || DialogResult.Yes == MessageBox.Show("Can't find page " +
                        currentPageNumber.ToString() + ". Do you want to go to page " + (currentPageNumber - 1).ToString() + " ?", "Can not find required page", MessageBoxButtons.YesNo, MessageBoxIcon.Question));
                    if (FindPageInMultiMode(currentPageNumber) > -1)
                        SelectDataGridViewCell(FindPageInMultiMode(currentPageNumber), dataGridViewInput.CurrentCell.ColumnIndex);
                }
            }
        }

        private void toolStripOpenExcelFileButton_Click(object sender, EventArgs e)
        {
            OpenExcelFile();
        }

        private void toolStripTextBoxFind_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
                toolStripButtonFind_Click(null, null);
        }

        #region Zoom and pan

        // tell us if our image has been clicked on
        public static Point startPoint;

        public static double zoomFactor = 1;
        private bool isMouseOverPicture = false;

        private void dataGridViewInput_MouseEnter(object sender, EventArgs e)
        {
            if (!dataGridViewInput.Focused)
                dataGridViewInput.Focus();
        }

        private void InputToolForm_MouseWheel(object sender, MouseEventArgs e)
        {
            if (isMouseOverPicture)
            {
                if (e.Delta > 0)
                {
                    toolStripButtonZoomIn_Click(null, null);
                }
                else
                {
                    toolStripButtonZoomOut_Click(null, null);
                }
            }

            // note: no really need this. More bugs to handle. Use in careful.
            // toolStripComboBoxZoomRatio.Focus();
        }

        /// <summary>
        /// limit the moving area of Zoomed Image
        /// </summary>

        private void PictBox_MouseDown(object sender, MouseEventArgs e)
        {
            PictBox.Focus();
            if (e.Button == MouseButtons.Left)
            {
                PictBox.Cursor = Cursors.SizeAll;
                startPoint = e.Location;
                panelPictBox.AutoScroll.ToString();
            }
        }

        private void PictBox_MouseEnter(object sender, EventArgs e)
        {
            isMouseOverPicture = true;
        }

        private void PictBox_MouseLeave(object sender, EventArgs e)
        {
            isMouseOverPicture = false;
        }

        /// <summary>
        /// Listen to mouse Event in PictBox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PictBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Point changePoint = new Point(e.Location.X - startPoint.X,
                                  e.Location.Y - startPoint.Y);
                panelPictBox.AutoScrollPosition = new Point(-panelPictBox.AutoScrollPosition.X - changePoint.X,
                                                      -panelPictBox.AutoScrollPosition.Y - changePoint.Y);
            }
        }

        private void RedrawPicture()
        {
            //DateTime t1 = new DateTime();
            
            if (navigationToolStripMenuItem.Checked)
            {
                DoubleRectangle rect;
                if (GlobalConstants.TemplatePageCol == 0)
                {
                    rect = GetCurrentCellRectSingleLine();
                }
                else
                {
                    rect = GetCurrentCellRectMultiLine();
                }
                PictBox.Image = tifImage.GetImageZoom(zoomFactor, rect);
                
            }
            else
            {
                PictBox.Image = tifImage.GetImageZoom(zoomFactor);
            }
            PictBox.Refresh();
            GC.Collect();
            // DateTime t2 = new DateTime();

        }

        private void PictBox_MouseUp(object sender, MouseEventArgs e)
        {
            PictBox.Cursor = Cursors.Default;
        }

        private void toolStripButtonZoomIn_Click(object sender, EventArgs e)
        {
            if (toolStripComboBoxZoomRatio.SelectedIndex < GlobalConstants.maxZoomIndex)
                toolStripComboBoxZoomRatio.SelectedIndex++;
        }

        private void toolStripButtonZoomOut_Click(object sender, EventArgs e)
        {
            if (toolStripComboBoxZoomRatio.SelectedIndex > 0)
                toolStripComboBoxZoomRatio.SelectedIndex--;
        }

        private void toolStripComboBoxZoomRatio_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (dataGridViewInput.CurrentCell == null) return;

            //PictBox.Focus();
            if (toolStripComboBoxZoomRatio.SelectedIndex < 0) toolStripComboBoxZoomRatio.SelectedIndex = 4; //handle exception

            // else init zoom
            int pos = toolStripComboBoxZoomRatio.Text.IndexOf('%');
            string zoomFactorString = toolStripComboBoxZoomRatio.Text.Remove(pos);
            zoomFactor = Convert.ToDouble(zoomFactorString) / 100;

            // active zoom buttons
            if (zoomFactor == GlobalConstants.minZoomFactor)
            {
                toolStripButtonZoomIn.Enabled = true;
                toolStripButtonZoomOut.Enabled = false;
            }
            else if (zoomFactor == GlobalConstants.maxZoomFactor)
            {
                toolStripButtonZoomIn.Enabled = false;
                toolStripButtonZoomOut.Enabled = true;
            }
            else
            {
                toolStripButtonZoomOut.Enabled = true;
                toolStripButtonZoomIn.Enabled = true;
            }

            RedrawPicture();
        }

        #endregion Zoom and pan

        private DoubleRectangle GetCurrentCellRectSingleLine()
        {
            return GlobalConstants.Columns[dataGridViewInput.CurrentCell.ColumnIndex].Rect;
        }

        private DoubleRectangle GetCurrentCellRectMultiLine()
        {
            DoubleRectangle sourceRect = GetCurrentCellRectSingleLine();

            int destCellRowIndex = dataGridViewInput.CurrentCell.RowIndex;

            if (dataGridViewInput.Rows[destCellRowIndex].Cells[GlobalConstants.TemplatePageCol - 1].Value == null)
                return sourceRect;

            object destPage = dataGridViewInput.Rows[destCellRowIndex].Cells[GlobalConstants.TemplatePageCol - 1].Value;

            int sourceCellRowIndex = destCellRowIndex;
            while (--sourceCellRowIndex >= 0)
            {
                if (dataGridViewInput.Rows[sourceCellRowIndex].Cells[GlobalConstants.TemplatePageCol - 1].Value!=null) // handle exception
                if ((dataGridViewInput.Rows[sourceCellRowIndex].Cells[GlobalConstants.TemplatePageCol - 1].Value.ToString())
                != destPage.ToString())
                {
                    int paddingLine = destCellRowIndex - sourceCellRowIndex - 1;
                    sourceRect.Y += sourceRect.Height * paddingLine;
                    return sourceRect;
                }
            }

            sourceRect.Y += sourceRect.Height * destCellRowIndex;

            return sourceRect;
        }

        #region zoom shortcut

        private void zoomIn2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripButtonZoomIn_Click(null, null);
        }

        private void zoomInToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripButtonZoomIn_Click(null, null);
        }

        private void zoomOut2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripButtonZoomOut_Click(null, null);
        }

        private void zoomOutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripButtonZoomOut_Click(null, null);
        }

        #endregion zoom shortcut

        private void toolStripTextBoxPageNumber_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                try
                {
                    int page = Convert.ToInt32(toolStripTextBoxPageNumber.Text);
                    int page_out=0;
                    if (GlobalConstants.TemplatePageCol == 0) // single mode
                    {
                        if (page > 0 && page <= dataGridViewInput.RowCount)
                            SelectDataGridViewCell(page - 1, dataGridViewInput.CurrentCell.ColumnIndex);
                        else
                            toolStripTextBoxPageNumber.Undo();
                    }
                    else
                    {
                        if (FindPageInMultiMode(page)>-1 )
                            {
                                SelectDataGridViewCell(FindPageInMultiMode(page), dataGridViewInput.CurrentCell.ColumnIndex);
                                return;
                            }
                        else
                            toolStripTextBoxPageNumber.Undo();
                    }
                    
                }
                catch
                {
                    toolStripTextBoxPageNumber.Undo();
                }
            }
        }

        private int FindPageInMultiMode(int pageNumber)
        {
            int page_out = 0;
            for (int i = 0; i < dataGridViewInput.RowCount; i++)
                
            {
                Int32.TryParse((dataGridViewInput.Rows[i].Cells[GlobalConstants.TemplatePageCol - 1].Value.ToString()), out page_out);
                if (page_out == pageNumber)
                    return i; 
            }
            return -1;
        }
        private bool LoadTemplate()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "FIS.iDET Template|*.fis";
            openFileDialog.Title = "Load template";
            openFileDialog.ShowDialog();
            if (openFileDialog.FileName != null && openFileDialog.FileName != "")
            {
                // reset vars
                GlobalConstants.Columns = null;
                GlobalConstants.DateColumnIndices = new List<int>();

                // get template info from XML (.fis file)
                bool ok = XmlService.ReadXml(openFileDialog.FileName);

                if (!ok)
                {
                    // cannot load data
                    MessageBox.Show("Cannot load template, please make sure that it is valid!");
                    return false;
                }
                else
                {
                    if (GlobalConstants.TemplatePageCol != 0)
                    {
                        dataGridViewInput.AllowUserToAddRows = true;
                        dataGridViewInput.AllowUserToDeleteRows = true; 
                        toolStripInsertNewRow.Enabled = true;
                        toolStripInsertNewRows.Enabled = true;
                    }
                    else
                    {
                        dataGridViewInput.AllowUserToAddRows = false;
                        dataGridViewInput.AllowUserToDeleteRows = false;
                        toolStripInsertNewRow.Enabled = false;
                        toolStripInsertNewRows.Enabled = false;
                    }
                    // set date column index array
                    for (int i = 0; i < GlobalConstants.Columns.Count; i++)
                    {
                        if (GlobalConstants.Columns[i].Type == DataTypeEnum.COLUMN_TYPE_DATE)
                            GlobalConstants.DateColumnIndices.Add(i);
                    }

                    return true;
                }
            }
            else
                return false;
        }

        private void toolStripButtonLoadTemplate_Click(object sender, EventArgs e)
        {
            LoadTemplate();
        }

        private void compareToolToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormMergeTool formCompare = new FormMergeTool();
            formCompare.ShowDialog();
        }

        private void dataGridViewInput_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                // var t1 = DateTime.Now;
                // get image frame for current row
                int frameToDisplay = 0;
                if (GlobalConstants.TemplatePageCol == 0)
                {
                    frameToDisplay = e.RowIndex;
                }
                else
                {
                    if (dataGridViewInput.Rows[e.RowIndex].Cells[GlobalConstants.TemplatePageCol - 1].Value != null)
                        frameToDisplay = Convert.ToInt32(dataGridViewInput.Rows[e.RowIndex].Cells[GlobalConstants.TemplatePageCol - 1].Value) - 1;
                }
                 
                
                if (frameToDisplay > tifImage.TotalFrames) return;

                // if image frame has changed
                if (navigationToolStripMenuItem.Checked && tifImage.CurrentFrame != frameToDisplay)
                {
                    for (int i = 0; i < GlobalConstants.ColumnsOriginalRects.Count; i++)
                        GlobalConstants.Columns[i].Rect = GlobalConstants.ColumnsOriginalRects[i];
                }
                /* var t2 = DateTime.Now;
                var t3 = DateTime.Now; */

                // get image
                if (tifImage.CurrentFrame != frameToDisplay || navigationToolStripMenuItem.Checked)
                {
                    tifImage.SetImageFrame(frameToDisplay);
                    // t3 = DateTime.Now;
                    RedrawPicture();
                }

/*                 var t4 = DateTime.Now;
                Debug.WriteLine("time1: " + (t2.Subtract(t1).TotalMilliseconds.ToString()) + 
                    " time 2: "+ (t3.Subtract(t2).TotalMilliseconds.ToString()) +
                    " time 3: "+ (t4.Subtract(t3).TotalMilliseconds.ToString()))                       
                    ;
                Debug.WriteLine("finish");
                */
                // update page number
                toolStripTextBoxPageNumber.Text = (frameToDisplay + 1).ToString();

                // update next & previous buttons state
                if (frameToDisplay == 0)
                    toolStripButtonPreviousPage.Enabled = false;
                else if (!toolStripButtonPreviousPage.Enabled)
                    toolStripButtonPreviousPage.Enabled = true;

                if (frameToDisplay == tifImage.TotalFrames - 1)
                    toolStripButtonNextPage.Enabled = false;
                else if (!toolStripButtonNextPage.Enabled)
                    toolStripButtonNextPage.Enabled = true;

                // tooltip
                if (navigationToolStripMenuItem.Checked)
                {
                    if (dataGridViewInput.CurrentCell != null
                    && dataGridViewInput.CurrentCell.ColumnIndex != GlobalConstants.TemplatePageCol - 1)
                    {
                        toolTipPictBoxDraw(dataGridViewInput.CurrentCell.Value);
                    }
                    else
                        toolTipPictBox.Hide(PictBox);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }
        }

        private void moveTooltipLeftToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (navigationToolStripMenuItem.Checked)
            {
                GlobalConstants.Columns[dataGridViewInput.CurrentCell.ColumnIndex].X -= Convert.ToInt32(toolStripComboBoxPosSpin.Text);
                RedrawPicture();
            }
        }

        private void moveTooltipRightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (navigationToolStripMenuItem.Checked)
            {
                GlobalConstants.Columns[dataGridViewInput.CurrentCell.ColumnIndex].X += Convert.ToInt32(toolStripComboBoxPosSpin.Text);
                RedrawPicture();
            }
        }

        private void moveTooltipUpToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (navigationToolStripMenuItem.Checked)
            {
                GlobalConstants.Columns[dataGridViewInput.CurrentCell.ColumnIndex].Y-=Convert.ToInt32(toolStripComboBoxPosSpin.Text);
                RedrawPicture();
            }
        }

        private void moveTooltipDownToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (navigationToolStripMenuItem.Checked)
            {
                GlobalConstants.Columns[dataGridViewInput.CurrentCell.ColumnIndex].Y += Convert.ToInt32(toolStripComboBoxPosSpin.Text);
                RedrawPicture();
            }
        }

        private void increaseTooltipHeightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (navigationToolStripMenuItem.Checked)
            {
                GlobalConstants.Columns[dataGridViewInput.CurrentCell.ColumnIndex].H++;
                RedrawPicture();
            }
        }

        private void increaseTooltipWidthToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (navigationToolStripMenuItem.Checked)
            {
                GlobalConstants.Columns[dataGridViewInput.CurrentCell.ColumnIndex].W++;
                RedrawPicture();
            }
        }

        private void decreaseTooltipHeightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (navigationToolStripMenuItem.Checked)
            {
                GlobalConstants.Columns[dataGridViewInput.CurrentCell.ColumnIndex].H--;
                RedrawPicture();
            }
        }

        private void decreaseTooltipWidthToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (navigationToolStripMenuItem.Checked)
            {
                GlobalConstants.Columns[dataGridViewInput.CurrentCell.ColumnIndex].W--;
                RedrawPicture();
            }
        }

        private void dataGridViewInput_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            TextBox tb = (TextBox)e.Control;
            tb.TextChanged -= new EventHandler(dataGridCell_TextChanged);
            tb.TextChanged += new EventHandler(dataGridCell_TextChanged);
        }

         private void dataGridCell_TextChanged(object sender, EventArgs e)
        {
             if (navigationToolStripMenuItem.Checked)
            {
                toolTipPictBoxDraw(((TextBox)sender).Text);
            }
         }

        private void toolTipPictBoxDraw(object text)
        {
            if (text == null) text = "";
            DoubleRectangle rect;
            if (GlobalConstants.TemplatePageCol == 0)
            {
                rect = GetCurrentCellRectSingleLine();
            }
            else
            {
                rect = GetCurrentCellRectMultiLine();
            }

            int x = (int)((rect.X + rect.Width) * zoomFactor) + 10;
            int y = (int)((rect.Y + rect.Height / 2) * zoomFactor) - 10;

            if (x > PictBox.Width || y > PictBox.Height) return;
            
            // in case image box has a scroll bar
            if ((PictBox.Width > panelPictBox.Width || PictBox.Height > panelPictBox.Height) && rect.X!=0 && rect.Y!=0 && rect.Width!=0 && rect.Height!=0 )
            {
                // get image visible area
                int offsetX = panelPictBox.HorizontalScroll.Value;
                int offsetY = panelPictBox.VerticalScroll.Value;
                int edgeX = offsetX + panelPictBox.Width - 20;
                int edgeY = offsetY + panelPictBox.Height - 20;

                // move tooltip in case it is outside of visible image area
                int rectXScaled = (int)(rect.X * zoomFactor) - (int)(GlobalConstants.offsetX * zoomFactor);
                if (rectXScaled < 0) rectXScaled = 0;
                int rectYScaled = (int)(rect.Y * zoomFactor) - (int)(GlobalConstants.offsetY * zoomFactor);
                if (rectYScaled < 0) rectYScaled = 0;
                if (rectXScaled < offsetX || rectXScaled + (rect.Width + GlobalConstants.offsetX) * zoomFactor > edgeX)
                {
                    // panelPictBox.HorizontalScroll.Value = rectXScaled;
                    panelPictBox.HorizontalScroll.Value = rectXScaled ;
                }
                if (rectYScaled < offsetY || rectYScaled + (rect.Height + GlobalConstants.offsetY) * zoomFactor > edgeY)
                {
                    panelPictBox.VerticalScroll.Value = rectYScaled ;
                }
            }

            if (rect.X != 0 && rect.Y != 0 && rect.Width != 0 && rect.Height != 0)
            {
                toolTipText = text is DateTime ? ((DateTime)text).ToString(comboBoxDateFormat.Text) : text.ToString();
                toolTipPictBox.Show(toolTipText, PictBox, x, y);
            }
        }

        private void toolStripComboBoxZoomRatio_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                int pos = toolStripComboBoxZoomRatio.Text.IndexOf('%');
                string zoomFactorString = toolStripComboBoxZoomRatio.Text;
                if (pos > -1)
                    zoomFactorString = toolStripComboBoxZoomRatio.Text.Remove(pos);
                else
                    toolStripComboBoxZoomRatio.Text += "%";
                double dzoomFactor = 0;
                
                // Ugly code here, use for identify the index of zoomComboBox
                int nzoomFactor =0;
                Int32.TryParse(zoomFactorString, out nzoomFactor);
                
                if (nzoomFactor > 0 && nzoomFactor <= GlobalConstants.maxZoomFactor*100)
                {
                    toolStripComboBoxZoomRatio.SelectedIndex = (nzoomFactor / 20)-1;
                    toolStripComboBoxZoomRatio.Text = zoomFactorString + "%";
                }

                // end zoomComboBox
                if (double.TryParse(zoomFactorString, out dzoomFactor) && dzoomFactor > 0 && dzoomFactor < (GlobalConstants.maxZoomFactor * 100))
                {
                    zoomFactor = Convert.ToDouble(zoomFactorString) / 100;
                    RedrawPicture();
                }
                else toolStripComboBoxZoomRatio.SelectedIndex = 4;
            }
        }

        private void toolStripButtonZoomFit_Click(object sender, EventArgs e)
        {
            // Calculate zoom factor
            int odd = 15;
            GlobalVariables.zoomMode = Math.Abs(GlobalVariables.zoomMode - 1);
            if (GlobalVariables.zoomMode == 0) // Fit width ( maybe ? )
                zoomFactor = (double)(panelPictBox.Width - odd) / (double)tifImage.Width;
            else
                zoomFactor = (double)(panelPictBox.Height - odd) / (double)tifImage.Height;
            int nzoomFactor = (int)(zoomFactor * 100);
            toolStripComboBoxZoomRatio.Text = nzoomFactor.ToString() + "%";
            KeyPressEventArgs key = new KeyPressEventArgs((char)Keys.Enter);
            toolStripComboBoxZoomRatio_KeyPress(null, key);
        }

        private void navigationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RedrawPicture();
        }

        private void zoomFitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripButtonZoomFit_Click(null, null);
        }

        private void toolStripButtonNavigationGuide_Click(object sender, EventArgs e)
        {
            navigationToolStripMenuItem.Checked = !navigationToolStripMenuItem.Checked;
            // change button image
            toolStripButtonNavigationGuide.Image =
                navigationToolStripMenuItem.Checked ?
                global::FIS.iDET.Properties.Resources.balloon :
                global::FIS.iDET.Properties.Resources.balloonOff;
            if (!navigationToolStripMenuItem.Checked)
                toolTipPictBox.Hide(PictBox);
            else
                if (dataGridViewInput.CurrentCell != null)
                    toolTipPictBoxDraw(dataGridViewInput.CurrentCell.Value);
            
            RedrawPicture();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripButtonLoadTemplate_Click(null, null);
        }

        private string toolTipText;

        private Font toolTipFont = new Font("Arial", 16);

        private void toolTipPictBox_Draw(object sender, DrawToolTipEventArgs e)
        {
            e.DrawBackground();
            e.DrawBorder();
            e.Graphics.DrawString(toolTipText, toolTipFont, Brushes.DarkOrange, 2, 2);
        }

        private Graphics gTooltip;

        private void toolTipPictBox_Popup(object sender, PopupEventArgs e)
        {
            SizeF size = gTooltip.MeasureString(toolTipText, toolTipFont);
            size.Width += 4;
            /*Graphics g = Graphics.FromImage(new Bitmap(1, 1));
            size.Width = _MeasureDisplayStringWidth(g, toolTipText,toolTipFont);
            size.Width += 6; */
            size.Height += 2;
            e.ToolTipSize = size.ToSize();
        }

        protected int _MeasureDisplayStringWidth(Graphics graphics, string text, Font font)
        {
            if (text == "")
                return 0;

            StringFormat format = new StringFormat(StringFormat.GenericDefault);
            RectangleF rect = new RectangleF(0, 0, 1000, 1000);
            CharacterRange[] ranges = { new CharacterRange(0, text.Length) };
            Region[] regions = new Region[1];

            format.SetMeasurableCharacterRanges(ranges);
            format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;

            regions = graphics.MeasureCharacterRanges(text, font, rect, format);
            rect = regions[0].GetBounds(graphics);

            return (int)(rect.Right);
        }

        private void toolStripInsertNewRow_Click(object sender, EventArgs e)
        {
            if (dataGridViewInput.CurrentCell != null)
            {
                int rowIndex = dataGridViewInput.CurrentCell.RowIndex + 1;
                if (rowIndex == dataGridViewInput.RowCount) rowIndex--;
                object[] newRowData = new object[dataGridViewInput.ColumnCount];
                newRowData[GlobalConstants.TemplatePageCol - 1] = dataGridViewInput.Rows[rowIndex].Cells[GlobalConstants.TemplatePageCol - 1].Value;
                dataGridViewInput.Rows.Insert(rowIndex, newRowData);
            }
        }

        
        

        

        private void deleteRowsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow item in dataGridViewInput.SelectedRows)
            {
                dataGridViewInput.Rows.RemoveAt(item.Index);
                dataGridViewInput.ClearSelection();
            }
        }

        private void dataGridViewInput_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
        {
            dataGridViewInput.ClearSelection();
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            string rows;
            rows = Interaction.InputBox("Number of new rows","Insert new rows", "1");
            int rowsNumber;
            if (int.TryParse(rows, out rowsNumber))
            {
                if (rowsNumber > 0)
                {
                    for (int i = 1; i <= rowsNumber; i++)
                        toolStripInsertNewRow_Click(sender, e);
                }
            }
        }
    }
}